package com.wjm.JavaSEAPI.APIstring;

/**
 * Data:2022年07月02日
 * Author:wjm
 * Content: String介绍
 * 
 */
/*
*
*1. String的特点
*    (1)String是不可变对象，，其底层是final char[] ，是常量，在JVM中位于字符串常量池，所谓常量介绍一旦创建就无法更改
*    (2)只要String的值发生变更，java的处理方式是创建一个新的String对象
*    (3)由于String是类，其实例为对象，Java处理对象传递都是“引用拷贝”
*    (4)对String的只读，任何引用都不会改变值
*
*
* 2.String常量池
*     常量池定义：
*        字符串常量池是JVM在堆中专门为字符串提供的一段科技，用来存放所有使用字面量(直接赋值)的形式创建的字符串，当再次使用相同
*     的字面量创建字符串时，JVM就会重用字符串常量池中的对象而不会再次重新创建，这就减少了内存的开销
*     常量池工作原理：
*        使用字符串常量池，每当我们创建字符常量时，JVM首先检查字符串常量池，如果字符串已经存在在常量池中，那么就直接返回常量池中
*     的实例引用，，如果字符串不存在常量池中，就会实例化该字符串并且放到常量池中。
*        由于String字符串的不可变性，我们可以十分的肯定常量池中一定不存在两个相同的字符集
*
*     编译器的特性：
*        当编译器在编译一段程序时，如发现是一段字面量表达式，那么它们的结果在编译期就是确定的，因此就会将得到的结果存入class文件
*     (而不是表达式)，好处就在于虚拟机运行程序时，不必每次都进行结果的计算。如String f = "123"+"123"那么f存入class文件的值，
*      应该是它们的结果"123123"
*
*     java中常量池分类：
*        实际上分两种：静态常量池和运行时常量池
*        静态常量池：即*.class文件中的常量池，class文件中的常量池不仅仅包含字符串(数字)字面量，还包含类，方法的信息，占用class
*     文件绝大部分空间。
*        运行时常量池： 则是JVM虚拟机在完成类装载操作后，将clss文件中的常量池载入到内存中，并保存在方法区中，我们常说的常量池，就
*     是指方法区中的运行时常量池
*
*
*
*3. equals()方法和 == 的比较
* String中的equals()方法
*     equals是继承自Object父类的，并对其进行的重写
*     作用是比较两个字符串的内容是否相同，相同返回true，不同返回false
*
* Object中的equals()方法
*     该父类中的equal()方法是用 == 进行判断的，但是许多业务需要比较的是对象中的内容是否相同，而非比较的是否是同一个对象，
* 如果不重写的话，无法达到想要的需求。
*
* == 在比较引用数据类型的时候，比较的是地址信息，只有是同一个对象的时候返回true。
*
* */
public class StringDemo {

    public static void main(String[] args) {

        StringDemo stringDemo = new StringDemo();
        //字符串创建对象的两种方式
        String a = new String("123");//不建议这么写
        String b = "123";
        String c = b;

        /*  a和b相等吗？  */
        System.out.println(a == b);//flase
        System.out.println(a.equals(b));//true

        //a,b的地址相同说明123这个字符串只在内存中存了一份
        System.out.println(a.hashCode());
        System.out.println(c.hashCode());
        System.out.println(b.hashCode());
        System.out.println("=================");

        //给c重新赋值后发现c的地址变了但是b没变说明了特点(2)
        c = "12345";
        System.out.println(c.hashCode());
        System.out.println(b.hashCode());
        System.out.println("=====================");

        //在method()方法中对main传进去的a进行更改，但是main方法中的a不变说明特点(3)
        System.out.println("这是main方法中的a的指"+a);
        System.out.println("这是main方法中的a的指"+a.hashCode());
        stringDemo.method(a);

        //下面这句话创建了4个对象：H一个，两个new ，"123"也算一个
        String H = new String("123")+new String("123");
    }
    public void method(String a){
        a = "12345";
        System.out.println("这是method方法中的a的指"+a);
        System.out.println("这是method方法中的a的指"+a.hashCode());
    }
}
